package com.szsh.aiot.hsm.thirdService;

import com.google.common.reflect.TypeToken;
import com.google.gson.Gson;
import com.szsh.aiot.hsm.dto.ability.GwInfo;
import com.szsh.aiot.hsm.dto.ability.NetTopologicalInfo;
import com.szsh.aiot.hsm.dto.ability.TopoInfo;
import com.szsh.aiot.hsm.utils.JsonConvert;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;

/**
 * 设备信息处理
 */
@Component
public class DeviceInfoClient {
    private static final Logger LOGGER = LoggerFactory.getLogger(DeviceInfoClient.class);

    @Autowired
    private AbilityClient abilityCilent;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    Gson gson = new Gson();

    /**
     * 调用拓扑接口，获取最近设备列表<br>
     * @return 拓扑列表
     */
    public List<TopoInfo> getTopoList(String gatewayMac) {
        // 查询拓扑接口
        NetTopologicalInfo netTopologicalInfo = abilityCilent.getTopologicalInfo(gatewayMac);
        if (null == netTopologicalInfo || null == netTopologicalInfo.getTopoInfo()) {
            if (LOGGER.isErrorEnabled()) {
                LOGGER.error("网关[{}]调用拓扑接口查询设备列表返回失败.", gatewayMac);
            }
            return new ArrayList<>();
        }

        String info = gson.toJson(netTopologicalInfo.getTopoInfo());
        if (StringUtils.isBlank(info)) {
            return new ArrayList<>();
        }
        return gson.fromJson(info, new TypeToken<List<TopoInfo>>(){}.getType());
    }


    /**
     * 调用拓扑接口，获取在线设备列表<br>
     * @return 在线设备列表
     */
    public List<TopoInfo> getOnlineTopoList(String gatewayMac) {
        // 查询拓扑接口
        NetTopologicalInfo netTopologicalInfo = abilityCilent.getTopologicalInfo(gatewayMac);
        if (null == netTopologicalInfo || null == netTopologicalInfo.getTopoInfo()) {
            if (LOGGER.isErrorEnabled()) {
                LOGGER.error("网关[{}]调用拓扑接口查询设备列表返回失败.", gatewayMac);
            }
            return new ArrayList<>();
        }

        String info = new Gson().toJson(netTopologicalInfo.getTopoInfo());
        if (StringUtils.isBlank(info)) {
            return new ArrayList<>();
        }

        GwInfo gwInfo = netTopologicalInfo.getGwInfo();
        if (null == gwInfo) {
            if (LOGGER.isErrorEnabled()) {
                LOGGER.error("网关[{}]调用拓扑接口查询设备列表返回网关信息错误.", gatewayMac);
            }
            return new ArrayList<>();
        }
        String gwLanIp = gwInfo.getLanIp();
        if (StringUtils.isBlank(gwLanIp)) {
            if (LOGGER.isErrorEnabled()) {
                LOGGER.error("网关[{}]调用拓扑接口查询设备列表返回网关信息错误.", gatewayMac);
            }
            return new ArrayList<>();
        }
        int index = gwLanIp.lastIndexOf(".");
        String gwLanIpPrefix = gwLanIp.substring(0, index);

        List<TopoInfo> returnTopoInfoList = new ArrayList<>();

        List<TopoInfo> topoInfoList =gson.fromJson(info,new TypeToken< List<TopoInfo>>(){}.getType());
        if (CollectionUtils.isNotEmpty(topoInfoList)) {
            for (TopoInfo topoInfo : topoInfoList) {
                if (1 == topoInfo.getActive()
                        && StringUtils.isNotBlank(topoInfo.getMac())
                        && StringUtils.isNotBlank(topoInfo.getIp())) {
                    String deviceIp = topoInfo.getIp();
                    if (Objects.equals(gwLanIpPrefix, deviceIp.substring(0, deviceIp.lastIndexOf(".")))) {
                        // 同一个C段
                        returnTopoInfoList.add(topoInfo);
                    }
                }
            }
        }

        if (LOGGER.isErrorEnabled()) {
            LOGGER.error("网关[{}]调用拓扑接口查询设备列表返回(在线).{}", gatewayMac, gson.toJson(returnTopoInfoList));
        }

        return returnTopoInfoList;
    }

}
